#ifndef __VE_CORE_THREADS_H__
#define __VE_CORE_THREADS_H__

/************************************************************************\
 * Thread                                                               *
\************************************************************************/

typedef struct VEThread VEThread;

typedef void (*VEThreadFunc)(void*);

VEThread * ve_thread_create( VEThreadFunc func, void *data );
void ve_thread_delete( VEThread *thread );

/************************************************************************\
 * Atomics                                                              *
\************************************************************************/

typedef volatile long VEAtomicInt;

#ifdef __GNUC__

#define ve_atomic_inc(a)                  __sync_fetch_and_add(a,1)
#define ve_atomic_dec(a)                  __sync_fetch_and_add(a,-1)
#define ve_atomic_cas(a, oldval, newval)  __sync_val_compare_and_swap(a, oldval, newval)
#define ve_atomic_swap(a, val)            __sync_lock_test_and_set(a, val)

#else /* __GNUC__ */

#define ve_atomic_inc(a)                  _InterlockedIncrement(a)
#define ve_atomic_dec(a)                  _InterlockedDecrement(a)
#define ve_atomic_cas(a, oldval, newval)  _InterlockedCompareExchange(a, newval, oldval)
#define ve_atomic_swap(a, val)            _InterlockedExchange(a, val)

#endif /* __GNUC__ */

#define ve_atomic_try_lock(guard) !ve_atomic_cas(guard, 0, 1)
#define ve_atomic_lock(guard)     while( !ve_atomic_try_lock(guard) ) ve_sleep(0)
#define ve_atomic_unlock(guard)   ve_atomic_swap(guard, 0)

/************************************************************************\
 * Mutex                                                                *
\************************************************************************/

typedef struct VEMutex VEMutex;

VEMutex * ve_mutex_create();
void ve_mutex_delete( VEMutex *mutex );
void ve_mutex_lock( VEMutex *mutex );
void ve_mutex_unlock( VEMutex *mutex );

/************************************************************************\
 * Thread events                                                        *
\************************************************************************/

typedef struct VEThreadEvent VEThreadEvent;

VEThreadEvent * ve_thread_event_create();
void ve_thread_event_delete( VEThreadEvent *event );
void ve_thread_event_signal( VEThreadEvent *event );
void ve_thread_event_wait( VEThreadEvent *event );

#endif /* __VE_CORE_THREADS_H__ */
